iT邦幫忙

2023 iThome 鐵人賽

DAY 12
0
DevOps

AWS ECS + Gitlab + Laravel + Terraform 從入門到摔坑系列 第 12

Day 12 連接世界的橋樑:CodePipeline

  • 分享至 

  • xImage
  •  

前面我們用 Gitlab pipeline build docker image 並且推上 ECR repository,ECS service 會用 ECR repository 內對應的 image 執行 container 提供服務。那麼有新 image 後是誰會把新 image deploy 到 ECS service 上呢?總不是要手動按吧?說好的自動化呢~?

今天我們要接上 CD 自動化的最後一塊拼圖:CodePipeline。利用 CodePipeline 在 ECR repository 有新的 image 時 trigger ECS deployment。 (筆者這麼懶怎麼可能自己按

CodePipeline 簡介

CodePipeline 是 AWS 管理的 continuous delivery 服務,讓我們可以自動化的進行各種部屬。

CodePipeline 的一個 pipeline 可以有多個 stage,每個 stage 可以執行多個 action,就像 Gitlab pipeline 的 stage 跟 job。CodePipeline 有整合其他服務,所以可以執行各種各樣的 action。

我們從最基本的擁有 Source、Build 以及 Deploy 三個 stage 的 pipeline 開始,三個 stage 主要做的事情是:

  • Source:從 ECR repository 取得 docker image

  • Build:建立 Deploy stage 需要的 metadata

  • Deploy:trigger ECS service 用新的 image deploy

建立 CodePipeline

老樣子,先用 web console 手動建立,進到 CodePipeline 的頁面:

https://ithelp.ithome.com.tw/upload/images/20230922/20160671xhZHyWPqZn.png

Create pipeline,讓它自己建立需要的 Role:

https://ithelp.ithome.com.tw/upload/images/20230922/20160671nApNID8lGo.png

新增第一個 stage Source:

https://ithelp.ithome.com.tw/upload/images/20230922/20160671v16yoUymE9.png

我們要從 ECR 拿 image 來 deploy,所以 source provider 選 Amazon ECR、選我們放 docker image 的 repository,image tag 留空讓它用預設的 latest 即可。image tag 用 latest 表示這個 tag 的 image 有變動的時候,會 trigger pipeline 執行。我們在 day6 的 gitlab pipeline push docker image 時除了有用日期時間當 tag,也會更新 latest 的 image,這樣才能把 gitlab pipeline 跟 CodePipeline 串起來。

接著第二個 stage build:

https://ithelp.ithome.com.tw/upload/images/20230922/20160671nPOqI6lJY2.png

這邊我們要用 AWS CodeBuild 執行簡單指令,來產生後面 deploy stage 需要的 metadata 檔案。

點 Create project 後會開一個新視窗來建立 CodeBuild project:

https://ithelp.ithome.com.tw/upload/images/20230922/20160671tquVsD9z11.png

環境部份簡單使用 Ubuntu 最新版本的 image,並讓它產生需要的 IAM role。

https://ithelp.ithome.com.tw/upload/images/20230922/20160671iUIijUfaXF.png

後面 additional configuration 都不動。

Buildspec 是我們指定要執行的指令的地方,它的格式是 YAML。我們直接切到 editor 貼指令:

https://ithelp.ithome.com.tw/upload/images/20230922/201606719UiwUgjZoT.png

在 Build commands 的編輯框貼上:

version: 0.2
phases:
    build:
        commands:
            - ContainerName="my-app"
            - ImageURI=$(cat imageDetail.json | jq -r '.ImageURI')
            - printf '[{"name":"CONTAINER_NAME","imageUri":"IMAGE_URI"}]' > imagedefinitions.json
            - sed -i -e "s|CONTAINER_NAME|$ContainerName|g" imagedefinitions.json
            - sed -i -e "s|IMAGE_URI|$ImageURI|g" imagedefinitions.json
 
artifacts:
    files:
        - imagedefinitions.json

這段指令設了兩個變數 ContainerNameImageURI ,一個是 task definition 裡 container 的名稱(my-app )、一個從 imageDetail.json 欄位 ImageURI 來。接著在 imagedefinitions.json 裡寫入一段 json,內容有 continaer 名稱跟 image uri。這段指令的產出物(artifacts)是 imagedefinitions.json 這個檔案。

為什麼要有 build stage 指令產生 imagedefinitions.json 呢?從 ECR 拿到 image 後叫 ECS deploy 就好了啊~?

這是因為 ECS 需要 imagedefinitions.json 這個檔案取得 container 相關資訊,像是要使用的新的 image 是什麼,然後產生新的 ECS service 的 task definition revision,最後讓 ECS service 使用新的 task definition revision 來跑 task。

那麼 imageDetail.json 又是哪來的?

imageDetail.json 是 pipeline 的 ECR source action 自動產生的,它會作為 source stage 的產出物(output artifact)給下一個 stage(也就是 build stage)使用,所以我們可以在這邊拿到 imageDetail.json

後面 Logs 部份都不勾:

https://ithelp.ithome.com.tw/upload/images/20230922/201606711Bg7YHNuEt.png

點 Continue to Codepipeline 會建立 CodeBuild project 並關閉這個新視窗。

回到 CodePipeline 可以看到已經選擇剛剛建立的 CodeBuild project:

https://ithelp.ithome.com.tw/upload/images/20230922/20160671isAOSyxyed.png

Next 繼續~

增加最後一個 stage Deploy,deploy provider 當然選 ECS 啦~ cluster 跟 service 照著建立的填就是了~

https://ithelp.ithome.com.tw/upload/images/20230922/201606712pOUhbFonr.png

Next 後會讓你 review 整個 CodePipeline 的設定,沒問題就 Create pipeline 吧!

pipeline 建立後,可以看它的執行過程:

https://ithelp.ithome.com.tw/upload/images/20230922/20160671efHXjv0dJh.png

順利的話,我們會看到三個 stage 都綠燈跑完表示 deploy 完成,這時候用瀏覽器開啟網站,就能看到新版程式的結果。

最後各位可以嘗試隨意改點程式碼,然後從 Gitlab 啟動一個 pipeline 看看整個從 Gitlab 到 CodePipeline 的 deploy 過程,再從 ALB DNS name 檢查新的程式碼是不是成功 deploy。一切順利的話,我們這就完成了從 Gitlab 開始的自動化 CD!(當然你可能不希望每次 push code 都 deploy 一次,就要調整 Gitlab deploy 相關 job 的觸發條件了~)

Reference


上一篇
Day 11 配合 ALB 的 ECS Service
下一篇
Day 13 初探 Terraform
系列文
AWS ECS + Gitlab + Laravel + Terraform 從入門到摔坑30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言